package com.mbc.hr.manager;

import java.util.List;

import javax.persistence.NoResultException;

import com.mbc.common.entities.Branch;
import com.mbc.common.exception.DataNotFoundException;
import com.mbc.common.manager.AbstractMgr;
import com.mbc.hr.data.EmployeeFingerPrintDeviceJunctionData;
import com.mbc.hr.entities.Department;
import com.mbc.hr.entities.Employee;
import com.mbc.hr.entities.EmployeeFingerPrintDeviceJunction;
import com.mbc.hr.entities.JobTitle;

public class EmployeeFingerPrintDeviceJunctionMgr extends AbstractMgr {
	public EmployeeFingerPrintDeviceJunctionMgr(){}
	
	public EmployeeFingerPrintDeviceJunctionMgr(String sessionId){
		this.sessionId  = sessionId;
	}

	public boolean isRegistered(long employeeID, long deviceID)throws Exception{
		openConnection();
		try {
			EmployeeFingerPrintDeviceJunction l_jun = entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.findByEmployeeIDNDeviceID", EmployeeFingerPrintDeviceJunction.class)
				.setParameter("employeeID", employeeID)
				.setParameter("deviceID", deviceID)
				.getSingleResult();
			return l_jun.isRegistered();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void registered(long employeeID, long deviceID)throws Exception{
		openConnection();
		try {
			beginTransaction();
			EmployeeFingerPrintDeviceJunction l_jun = entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.findByEmployeeIDNDeviceID", EmployeeFingerPrintDeviceJunction.class)
				.setParameter("employeeID", employeeID)
				.setParameter("deviceID", deviceID)
				.getSingleResult();
			l_jun.setRegistered(true);
			entityManager.merge(l_jun);
			commitTransaction();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void updateJunction(List<Long> addedDeviceIDList, List<Long> deletedDeviceIDList, String employeeNo)throws Exception{
		openConnection();
		try {
			beginTransaction();
			Employee l_emp = entityManager.createNamedQuery("Employee.findByEmployeeNo", Employee.class)
					.setParameter("employeeNo", employeeNo)
					.getSingleResult();
			if(l_emp.getFingerPrintID() == 0){
				l_emp.setFingerPrintID(FingerPrintDeviceMgr.generateFingerPrintID(entityManager));
				entityManager.merge(l_emp);
			}
			
			for (Long l_devID : deletedDeviceIDList) {
				entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.deleteByEmployeeIDNDeviceID")
				.setParameter("employeeID", l_emp.getEmployeeID())
				.setParameter("deviceID", l_devID)
				.executeUpdate();
			}
			
			for (Long l_devID : addedDeviceIDList) {
				EmployeeFingerPrintDeviceJunction l_jun = new EmployeeFingerPrintDeviceJunction();
				l_jun.setDeviceID(l_devID);
				l_jun.setEmployeeID(l_emp.getEmployeeID());
				entityManager.persist(l_jun);
			}
			commitTransaction();
		}
		catch (NoResultException e){
			rollbackTransaction();
			throw new DataNotFoundException("Employee No. " + employeeNo + " is not found.");
		}
		catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void deleteJunctionByEmployeeNo(String employeeNo)throws Exception{
		openConnection();
		try {
			beginTransaction();
			Employee l_emp = entityManager.createNamedQuery("Employee.findByEmployeeNo", Employee.class)
					.setParameter("employeeNo", employeeNo)
					.getSingleResult();
			l_emp.setFingerPrintID((long)0);
			entityManager.merge(l_emp);
			
			entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.deleteByEmployeeID")
				.setParameter("employeeID", l_emp.getEmployeeID())
				.executeUpdate();
			commitTransaction();
		} catch (NoResultException e){
			rollbackTransaction();
			throw new DataNotFoundException("Employee No. " + employeeNo + " is not found.");
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public List<EmployeeFingerPrintDeviceJunction> getJunctions(String employeeNo)throws Exception{
		openConnection();
		try {
			Employee l_emp = entityManager.createNamedQuery("Employee.findByEmployeeNo", Employee.class)
					.setParameter("employeeNo", employeeNo)
					.getSingleResult();
			return entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.findEmployeeID", EmployeeFingerPrintDeviceJunction.class)
			.setParameter("employeeID", l_emp.getEmployeeID())
			.getResultList();
		} catch (NoResultException e){
			throw new DataNotFoundException("Employee No. " + employeeNo + " is not found.");
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public EmployeeFingerPrintDeviceJunctionData getJunctionData(String employeeNo)throws Exception{
		openConnection();
		try {
			Employee l_emp = entityManager.createNamedQuery("Employee.findByEmployeeNo", Employee.class)
					.setParameter("employeeNo", employeeNo)
					.getSingleResult();
			
			EmployeeFingerPrintDeviceJunctionData l_data = new EmployeeFingerPrintDeviceJunctionData();
			l_data.setEmployeeID(l_emp.getEmployeeID());
			l_data.setEmployeeNo(l_emp.getEmployeeNo());
			l_data.setName(l_emp.getName());
			l_data.setEmployeeFingerPrintID(l_emp.getFingerPrintID());
			l_data.setJobTitle(entityManager.find(JobTitle.class, l_emp.getJobTitleID()).getTitle());
			l_data.setBranch(entityManager.find(Branch.class, l_emp.getBranchId()).getName());
			if(l_emp.getDepartmentID() != null)
				l_data.setDepartment(entityManager.find(Department.class, l_emp.getDepartmentID()).getDepartmentName());

			l_data.setJunctions(entityManager.createNamedQuery("EmployeeFingerPrintDeviceJunction.findEmployeeID", EmployeeFingerPrintDeviceJunction.class)
					.setParameter("employeeID", l_emp.getEmployeeID())
					.getResultList());
			
			return l_data;
			
		} catch (NoResultException e){
			throw new DataNotFoundException("Employee No. " + employeeNo + " is not found.");
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
}
